package com.zenithmind.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.article.mapper.ArticleLikeMapper;
import com.zenithmind.article.mapper.ArticleMapper;
import com.zenithmind.article.pojo.domain.Article;
import com.zenithmind.article.pojo.domain.ArticleLike;
import com.zenithmind.article.service.ArticleLikeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.BeanUtils;

import java.util.Objects;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.annotation.DataCacheEvict;
import com.zenithmind.common.constant.CacheConstants;
import com.zenithmind.common.security.SecurityUtils;

/**
 * <p>
 * 文章点赞 服务实现类
 * </p>
 *
 * @author zenithmind
 * @since 2023-10-26
 */
@Service
@Slf4j
public class ArticleLikeServiceImpl extends ServiceImpl<ArticleLikeMapper, ArticleLike> implements ArticleLikeService {

    @Autowired
    private ArticleMapper articleMapper;
    
    // 缓存前缀常量
    private static final String CACHE_ARTICLE_LIKE_PREFIX = "article:like";
    private static final String CACHE_USER_LIKE_PREFIX = "user:article:like";

    /**
     * 点赞或取消点赞文章
     *
     * @param articleId 文章ID
     * @return 当前点赞状态，true为已点赞，false为未点赞
     */
    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_USER_LIKE_PREFIX, key = "#result.userId + ':' + #articleId")
    public ArticleLike toggleLike(String articleId) {
        // 获取当前用户ID
        String userId = SecurityUtils.getCurrentUserId();
        log.info("用户 {} 点赞/取消点赞文章 {}", userId, articleId);

        // 校验文章是否存在
        Article article = articleMapper.selectById(articleId);
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }

        // 查询当前用户是否已点赞该文章
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleId)
                .eq(ArticleLike::getUserId, userId);
        ArticleLike articleLike = baseMapper.selectOne(queryWrapper);

        if (articleLike == null) {
            // 用户未点赞，创建点赞记录
            articleLike = new ArticleLike();
            articleLike.setArticleAndUser(articleId, userId);
            baseMapper.insert(articleLike);

            // 更新文章点赞数
            updateArticleLikeCount(articleId, 1);
            log.info("用户 {} 点赞文章 {}", userId, articleId);
        } else {
            // 用户已点赞，删除点赞记录
            baseMapper.deleteById(articleLike.getId());

            // 更新文章点赞数
            updateArticleLikeCount(articleId, -1);
            log.info("用户 {} 取消点赞文章 {}", userId, articleId);
            
            // 重新设置为null，表示用户已取消点赞
            articleLike = null;
        }

        return articleLike;
    }

    /**
     * 检查用户是否已点赞文章
     *
     * @param articleId 文章ID
     * @param userId 用户ID
     * @return 是否已点赞
     */
    @Override
    @DataCache(prefix = CACHE_USER_LIKE_PREFIX, key = "#userId + ':' + #articleId", 
              expireTime = CacheConstants.TTL_SECONDS_DEFAULT)
    public boolean checkUserLiked(String articleId, String userId) {
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleId)
                .eq(ArticleLike::getUserId, userId);
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 获取文章点赞数
     *
     * @param articleId 文章ID
     * @return 点赞数
     */
    @Override
    @DataCache(prefix = CACHE_ARTICLE_LIKE_PREFIX, key = "#articleId + ':count'", 
              expireTime = CacheConstants.TTL_SECONDS_DEFAULT)
    public long getLikeCount(String articleId) {
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleId);
        return baseMapper.selectCount(queryWrapper);
    }

    /**
     * 更新文章点赞数
     *
     * @param articleId 文章ID
     * @param delta 增量，可以为正数或负数
     */
    private void updateArticleLikeCount(String articleId, int delta) {
        Article article = articleMapper.selectById(articleId);
        if (article != null) {
            // 获取当前点赞数
            Integer currentLikeCount = article.getLikeCount();
            if (currentLikeCount == null) {
                currentLikeCount = 0;
            }
            
            // 计算新的点赞数
            int newLikeCount = Math.max(0, currentLikeCount + delta); // 确保不会出现负数
            
            // 更新文章点赞数
            article.updateLikeCount(newLikeCount);
            articleMapper.updateById(article);
        }
    }

    /**
     * 获取用户是否点赞过指定文章
     *
     * @param articleId 文章ID
     * @return 是否点赞过
     */
    @Override
    @DataCache(prefix = CACHE_USER_LIKE_PREFIX, key = "#result.userId + ':' + #articleId", 
              expireTime = CacheConstants.TTL_SECONDS_DEFAULT)
    public ArticleLike getUserLike(String articleId) {
        String userId = SecurityUtils.getCurrentUserId();
        
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleId)
                .eq(ArticleLike::getUserId, userId);
        
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * 获取文章点赞状态
     *
     * @param articleLike 文章点赞对象
     * @return 文章点赞状态
     */
    @Override
    @DataCache(prefix = CACHE_ARTICLE_LIKE_PREFIX, key = "#articleLike.id", 
              expireTime = CacheConstants.TTL_SECONDS_DEFAULT)
    public boolean getArticleLikeStatus(ArticleLike articleLike) {
        if (articleLike == null || articleLike.getArticleId() == null || articleLike.getUserId() == null) {
            return false;
        }
        
        // 查询是否存在点赞记录
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleLike.getArticleId())
                .eq(ArticleLike::getUserId, articleLike.getUserId());
        
        return baseMapper.selectCount(queryWrapper) > 0;
    }
    
    /**
     * 添加或更新文章点赞
     *
     * @param articleLike 文章点赞对象
     */
    @Override
    @Transactional
    @DataCacheEvict(prefix = CACHE_ARTICLE_LIKE_PREFIX, key = "#articleLike.articleId + ':count'")
    public void addOrUpdateArticleLike(ArticleLike articleLike) {
        if (articleLike == null || articleLike.getArticleId() == null) {
            throw new RuntimeException("文章ID不能为空");
        }
        
        // 如果没有指定用户ID，使用当前用户ID
        String currentUserId = SecurityUtils.getCurrentUserId();
        articleLike.setArticleAndUser(articleLike.getArticleId(), currentUserId);
        
        // 查询是否已经存在点赞记录
        LambdaQueryWrapper<ArticleLike> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ArticleLike::getArticleId, articleLike.getArticleId())
                .eq(ArticleLike::getUserId, articleLike.getUserId());
        ArticleLike existingLike = baseMapper.selectOne(queryWrapper);
        
        if (existingLike != null) {
            // 已存在点赞记录，更新
            BeanUtils.copyProperties(articleLike, existingLike, "id", "createTime");
            baseMapper.updateById(existingLike);
        } else {
            // 不存在点赞记录，新增
            baseMapper.insert(articleLike);
            
            // 更新文章点赞数
            updateArticleLikeCount(articleLike.getArticleId(), 1);
        }
    }
}
